<template>
  <div>
    <Card title="用例结果查询" :bordered="false" :dis-hover="true">
      <div slot="extra">
        <Button
          size="small"
          type="primary"
          icon="ios-search"
          class="card-extra-item"
          @click="search"
          >查询</Button
        >
        <Button
          size="small"
          type="default"
          icon="ios-refresh"
          class="card-extra-item"
          @click="reset"
          >重置</Button
        >
      </div>
      <Form
        inline
        label-position="right"
        :label-width="100"
        :model="searchParams"
      >
        <Row>
          <Col span="6">
            <FormItem label="用例名称">
              <Input
                clearable
                placeholder="请输入用例名称"
                v-model="searchParams.testcase_name"
              />
            </FormItem>
          </Col>
          <Col span="6">
            <FormItem label="所属项目">
              <Select
                v-model="searchParams.project"
                filterable
                clearable
                @on-change="changeProjectOption"
              >
                <Option
                  v-for="item in projects"
                  :value="item.id"
                  :key="item.id"
                  >{{ item.name }}</Option
                >
              </Select>
            </FormItem>
          </Col>
          <Col span="6">
            <FormItem label="请求接口">
              <Select
                v-model="searchParams.api"
                :max-tag-count="1"
                clearable
                multiple
                filterable
                size="default"
              >
                <Option
                  v-for="item in apis"
                  :key="item.id"
                  :value="item.id"
                  :label="item.name"
                />
              </Select>
            </FormItem>
          </Col>
          <Col span="6">
            <FormItem label="测试结果">
              <Select v-model="searchParams.status" clearable>
                <Option value="PASS">通过</Option>
                <Option value="FAIL">失败</Option>
              </Select>
            </FormItem>
          </Col>
        </Row>
      </Form>
    </Card>
    <Card title="用例结果列表" :bordered="false" :dis-hover="true">
      <div slot="extra">
        <span class="card-extra-item">
          <Icon size="24" :color="statusColor['PASS']" type="ios-leaf" />通过
        </span>
        <span class="card-extra-item">
          <Icon
            size="24"
            :color="statusColor['PARTIAL_PASS']"
            type="ios-leaf"
          />部分通过
        </span>
        <span class="card-extra-item">
          <Icon size="24" :color="statusColor['FAIL']" type="ios-leaf" />失败
        </span>
        <Poptip
          title="确定要删除?"
          :confirm="true"
          :transfer="true"
          @on-ok="handleDeleteTestcaseResult()"
        >
          <Button class="card-extra-item" size="small" type="error"
            >删除</Button
          >
        </Poptip>
      </div>
      <div class="version_container">
        <div class="version_header">
          <span>最新报告 Top10</span>
          <Button
            icon="md-refresh"
            size="small"
            type="text"
            style="color: #2d8cf0"
            @click="getTestcaseResultVersions('refresh')"
            >刷新</Button
          >
        </div>
        <div class="version_body">
          <Tag
            v-for="(item, index) in versions"
            :key="index"
            @click.native="showTestcaseReport(item.version)"
            :color="statusColor[item.status]"
            type="border"
            style="cursor: pointer"
          >
            {{ Number(item.version) | dateFormat("YYYY-MM-DD HH:mm:ss.SSS") }}
          </Tag>
        </div>
      </div>
      <Table
        :columns="testcaseResultColumns"
        :data="testcaseResultData"
        border
        size="small"
        :tooltip-max-width="500"
        @on-selection-change="selectionChange"
      >
        <template slot-scope="{ row }" slot="project|api">
          <Tooltip placement="bottom" transfer :max-width="500">
            <div slot="content" style="white-space: normal">
              项目：{{ row.project_name }}
              <br />
              接口：{{ row.api_name }}
            </div>
            {{ row.project_name }} - {{ row.api_name }}
          </Tooltip>
        </template>
        <template slot-scope="{ row }" slot="status">
          <Icon size="24" :color="statusColor[row.status]" type="ios-leaf" />
        </template>
        <template slot-scope="{ row }" slot="action">
          <Button
            size="small"
            type="text"
            style="color: #2d8cf0"
            @click="showDetails(row)"
            >详情</Button
          >
          <Button
            size="small"
            type="text"
            style="color: #2d8cf0"
            @click="showTestcaseReport(row.version)"
            >报告</Button
          >
        </template>
      </Table>
      <Page
        transfer
        :total="page.total"
        :current="page.current"
        :page-size="page.pageSize"
        :page-size-opts="page.pageSizeOpts"
        size="small"
        show-elevator
        show-sizer
        show-total
        prev-text="上一页"
        next-text="下一页"
        style="margin-top: 15px"
        @on-change="change"
        @on-page-size-change="pageSizeChange"
      />
    </Card>
  </div>
</template>

<script>
import { getProjectNames } from "@/api/HttpAutoTestService/project";
import { getApiNames } from "@/api/HttpAutoTestService/api";
import {
  getTestcaseResults,
  batchDeleteTestcaseResult,
  getTestcaseResultVersions,
} from "@/api/HttpAutoTestService/testcase-result";

export default {
  name: "testcase-result",

  mounted() {
    this.search();
    getProjectNames()
      .then((res) => {
        this.projects = res.data;
      })
      .catch((err) => {
        this.$Modal.error({
          title: "系统异常，请联系管理员……",
          content: JSON.stringify(err),
          closable: true,
        });
      });
    getApiNames()
      .then((res) => {
        this.apis = res.data;
      })
      .catch((err) => {
        this.$Modal.error({
          title: "系统异常，请联系管理员……",
          content: JSON.stringify(err),
          closable: true,
        });
      });
    this.getTestcaseResultVersions();
  },
  data() {
    return {
      statusColor: {
        PASS: "#19be6b",
        PARTIAL_PASS: "#ff9900",
        FAIL: "#ed4014",
      },
      searchParams: {
        testcase_name: "",
        project: "",
        api: [],
        status: "",
      },
      testcaseResultColumns: [
        {
          type: "selection",
          width: 60,
          align: "center",
          fixed: "left",
        },
        {
          title: "用例名称",
          key: "testcase_name",
          width: 350,
          tooltip: true,
          align: "center",
        },
        {
          title: "项目|接口",
          slot: "project|api",
          width: 350,
          ellipsis: true,
          align: "center",
        },
        {
          title: "请求URL",
          key: "url",
          width: 350,
          tooltip: true,
          align: "center",
        },
        {
          title: "响应状态码",
          key: "actual_status_code",
          width: 100,
          align: "center",
        },
        {
          title: "响应时长(ms)",
          key: "elapsed_ms",
          width: 120,
          align: "center",
        },
        {
          title: "响应结果",
          key: "actual_response_data",
          minWidth: 350,
          align: "center",
          ellipsis: true,
        },
        {
          title: "输出变量结果",
          key: "output_result",
          minWidth: 350,
          align: "center",
          ellipsis: true,
        },
        {
          title: "失败原因",
          key: "failure_reason",
          minWidth: 350,
          align: "center",
          ellipsis: true,
        },
        {
          title: "执行时间",
          key: "execute_time",
          width: 150,
          align: "center",
        },
        {
          title: "执行人",
          key: "executor_real_name",
          align: "center",
          width: 120,
        },
        {
          title: "版本",
          key: "version",
          align: "center",
          width: 130,
        },
        {
          title: "测试结果",
          slot: "status",
          align: "center",
          width: 85,
          fixed: "right",
        },
        {
          title: "操作",
          slot: "action",
          align: "center",
          width: 125,
          fixed: "right",
        },
      ],
      testcaseResultData: [],
      projects: [],
      apis: [],
      selectedTestcaseResults: [],
      page: {
        current: 1,
        total: 0,
        pageSize: 50,
        pageSizeOpts: [10, 30, 50, 100, 200],
      },
      versions: [],
    };
  },
  methods: {
    reset() {
      this.searchParams = {
        testcase_name: "",
        project: "",
        api: [],
        status: "",
      };
      this.search();
    },
    search(page) {
      let data = {
        testcase_name: this.searchParams.testcase_name,
        project: this.searchParams.project,
        api: this.searchParams.api.toString(),
        status: this.searchParams.status,
        page: 1,
        page_size: this.page.pageSize,
        testsuite_result: "null",
      };
      if (typeof page == "number") {
        data.page = page;
      }
      this.page.current = data.page;

      getTestcaseResults(data)
        .then((res) => {
          const data = res.data;
          this.testcaseResultData = data.results;
          this.page.total = data.count;
          if (data.next === null) {
            this.page.current = Math.ceil(this.page.total / this.page.pageSize);
          }
          if (data.previous === null) {
            this.page.current = 1;
          }
        })
        .catch((err) => {
          this.$Modal.error({
            title: "系统异常，请联系管理员……",
            content: JSON.stringify(err),
            closable: true,
          });
        });
    },
    change(val) {
      this.page.current = val;
      this.search(val);
    },
    pageSizeChange(val) {
      this.page.pageSize = val;
      this.search();
    },
    showDetails(row) {
      this.$router.push({
        name: "testcase_result_detail",
        query: { id: row.id },
      });
    },
    selectionChange(val) {
      this.selectedTestcaseResults = val.map((item) => {
        return item.id;
      });
    },
    changeProjectOption(val) {
      let data = {};
      if (val !== undefined) {
        data["project"] = val;
      }
      getApiNames(data).then((res) => {
        this.apis = res.data;
        let apiTemp = [];
        if (Array.isArray(this.apis) && this.searchParams.api.length > 0) {
          apiTemp = this.searchParams.api.filter((apiId) => {
            return JSON.stringify(this.apis).indexOf(apiId) !== -1;
          });
        }

        if (Array.isArray(this.apis) && this.apis.length === 0) {
          apiTemp = [];
        }

        this.searchParams.api = apiTemp;
      });
    },
    handleDeleteTestcaseResult() {
      let data = {
        testcaseResults: this.selectedTestcaseResults,
      };
      batchDeleteTestcaseResult(data)
        .then((res) => {
          const status = res.status;
          if (status === 204) {
            this.$Message.info("删除成功");
          }
          this.search();
          this.getTestcaseResultVersions();
          this.selectedTestcaseResults = [];
        })
        .catch((err) => {
          this.$Modal.error({
            title: "系统异常，请联系管理员……",
            content: JSON.stringify(err),
            closable: true,
          });
        });
    },
    showTestcaseReport(version) {
      let routeUrl = this.$router.resolve({
        name: "report",
        params: { type: "testcase", version: version },
      });
      window.open(routeUrl.href, "_blank");
    },
    getTestcaseResultVersions(val) {
      getTestcaseResultVersions()
        .then((res) => {
          this.versions = res.data;
          const statusCode = res.status;
          if (statusCode === 200 && val === "refresh") {
            this.$Message.info("最新报告 Top10 刷新成功……");
          }
        })
        .catch((err) => {
          this.$Modal.error({
            title: "系统异常，请联系管理员……",
            content: JSON.stringify(err),
            closable: true,
          });
        });
    },
  },
};
</script>

<style lang="less" scoped>
.version_container {
  border: 1px solid #dcdee2;
  padding: 5px;
  margin: 0 0 5px 0;
  border-radius: 4px;

  .version_header {
    display: flex;
    justify-content: space-between;
    margin: 0 0 5px 0;
    padding: 2px 4px;
    border-bottom: 1px solid #e8eaec;
  }

  .version_body {
    display: flex;
    justify-content: space-between;
  }
}
.ivu-form-item {
  width: 100%;
}
</style>
